using System.IO;
using Core.Extensions;
using EmbeddedWebserver.Core.Configuration;


namespace SolarDevices.Configuration
{
    public class Configuration 
    {
        private const string CONFIGURATION_DHCP = "network.DHCPEnabled";
        private const string CONFIGURATION_NETBIOSNAME = "network.NetbiosName";
        private const string CONFIGURATION_GATEWAY = "network.gatewayIp";
        private const string CONFIGURATION_SUBNET = "network.subnet";
        private const string CONFIGURATION_DEVICE_IP = "network.deviceIp";
        private const string CONFIGURATION_KEY_WEB_PORT = "network.port";
        private const string CONFIGURATION_POWER_SCALE = "solar.powerScale";
        private const string CONFIGURATION_MAX_PV_VOLTAGE = "solar.maxPVVoltage";
        private const string CONFIGURATION_BATTERY_VOLTAGE_SCALE = "solar.batteryVoltageScale";
        private const string CONFIGURATION_KEY_INVERTER = "solar.inverter";
        private const string CONFIGURATION_KEY_LCD = "system.LCDEnabled";
        private const string CONFIGURATION_KEY_CHARGE_CONTROLLER = "solar.controller";
        private const string CONFIGURATION_KEY_MODBUS_SLAVE_IP = "modbus.slaveIp";
        private const string CONFIGURATION_KEY_MODBUS_PORT = "modbus.port";
        private const string CONFIGURATION_KEY_WEB_MAX_WORKER_THREAD_COUNT = "web.maxthreadcount";

        private const char VALUE_SEPARATOR = '=';

        #region Constructors

        public Configuration(string configurationFilePath, string root)
        {
            _configurationFile = configurationFilePath;
            _modbusConfiguration = new ModbusConfiguration();
            _solarConfiguration = new SolarConfiguration();
            _systemConfiguration = new SystemConfiguration();
            _webConfiguration = new EmbeddedWebapplicationConfiguration(root);
        }

        #endregion

        private readonly IModbusConfiguration _modbusConfiguration;
        private readonly ISolarConfiguration _solarConfiguration;
        private readonly ISystemConfiguration _systemConfiguration;
        private readonly IEmbeddedWebapplicationConfiguration _webConfiguration;

        private readonly string _configurationFile;

        public IModbusConfiguration ModbusConfiguration
        {
            get { return _modbusConfiguration; }
        }

        public ISolarConfiguration SolarSystem
        {
            get { return _solarConfiguration; }
        }

        public ISystemConfiguration SystemConfiguration
        {
            get { return _systemConfiguration; }
        }

        public IEmbeddedWebapplicationConfiguration WebConfiguration
        {
            get { return _webConfiguration; }
        }

        public void ReadConfiguration()
        {
            using (FileStream fileStream = File.Open(_configurationFile, FileMode.Open, FileAccess.Read))
            {
                using (var reader = new StreamReader(fileStream))
                {
                    string currentLine;
                    while (!(currentLine = reader.ReadLine()).IsNullOrEmpty())
                    {
                        string[] values = currentLine.Split(new[] { VALUE_SEPARATOR }, 2);
                        string key = values[0].Trim();
                        switch (key)
                        {
                            case CONFIGURATION_DHCP:
                                SystemConfiguration.DHCPEnabled = values[1].Trim().Equals("true");
                                break;
                            case CONFIGURATION_NETBIOSNAME:
                                SystemConfiguration.NetBiosName = values[1].Trim();
                                break;
                            case CONFIGURATION_GATEWAY:
                                SystemConfiguration.GatewayIp = values[1].Trim();
                                break;
                            case CONFIGURATION_SUBNET:
                                SystemConfiguration.SubnetMask = values[1].Trim();
                                break;
                            case CONFIGURATION_DEVICE_IP:
                                SystemConfiguration.DeviceIp = values[1].Trim();
                                break;
                            case CONFIGURATION_KEY_MODBUS_SLAVE_IP:
                                ModbusConfiguration.ModbusSlaveIp = values[1].Trim();
                                break;
                            case CONFIGURATION_KEY_MODBUS_PORT:
                                ModbusConfiguration.ModbusSlavePort = ushort.Parse(values[1].Trim());
                                break;
                            case CONFIGURATION_KEY_WEB_PORT:
                                WebConfiguration.Port = ushort.Parse(values[1].Trim());
                                break;
                            case CONFIGURATION_KEY_WEB_MAX_WORKER_THREAD_COUNT:
                                WebConfiguration.MaxWorkerThreadCount = ushort.Parse(values[1].Trim());
                                break;
                            case CONFIGURATION_KEY_INVERTER:
                                if (values[1].Trim().Equals("None"))
                                {
                                        SolarSystem.Inverter = InverterType.None;
                                }
                                else if (values[1].Trim().Equals("Outback"))
                                {
                                    SolarSystem.Inverter = InverterType.Outback;
                                }
                                break;
                            case CONFIGURATION_KEY_CHARGE_CONTROLLER:
                                if (values[1].Trim().Equals("Classic"))
                                {
                                    SolarSystem.ChargeController = ChargeControllerType.Classic;
                                }
                                else if (values[1].Trim().Equals("Outback"))
                                {
                                    SolarSystem.ChargeController = ChargeControllerType.Outback;
                                }
                                else if (values[1].Trim().Equals("TriStarTCP"))
                                {
                                    SolarSystem.ChargeController = ChargeControllerType.TriStarTCP;
                                }
                                else if (values[1].Trim().Equals("TriStarRTU"))
                                {
                                    SolarSystem.ChargeController = ChargeControllerType.TriStarRTU;
                                }
                                break;
                            case CONFIGURATION_POWER_SCALE:
                                SolarSystem.PowerScale = int.Parse(values[1].Trim());
                                break;
                            case CONFIGURATION_MAX_PV_VOLTAGE:
                                SolarSystem.MaxPVVoltage = int.Parse(values[1].Trim());
                                break;
                            case CONFIGURATION_BATTERY_VOLTAGE_SCALE:
                                SolarSystem.BatteryVoltageScale = int.Parse(values[1].Trim());
                                break;
                            case CONFIGURATION_KEY_LCD:
                                SystemConfiguration.LCDEnabled = values[1].Trim().Equals("true");
                                break;

                        }
                    }
                }
            }
        }

        public void SaveConfiguration()
        {
            File.Delete(_configurationFile);
            using (var fileStream = File.Open(_configurationFile, FileMode.CreateNew, FileAccess.Write))
            {
                using (var writer = new StreamWriter(fileStream))
                {
                    writer.WriteLine(string.Concat(CONFIGURATION_POWER_SCALE, "=", SolarSystem.PowerScale));
                    writer.WriteLine(string.Concat(CONFIGURATION_MAX_PV_VOLTAGE, "=", SolarSystem.MaxPVVoltage));
                    writer.WriteLine(string.Concat(CONFIGURATION_BATTERY_VOLTAGE_SCALE, "=", SolarSystem.BatteryVoltageScale));
                    switch (SolarSystem.Inverter)
                    {
                        case InverterType.None:
                            writer.WriteLine(string.Concat(CONFIGURATION_KEY_INVERTER, "=", "None"));
                            break;
                        case InverterType.Outback:
                            writer.WriteLine(string.Concat(CONFIGURATION_KEY_INVERTER, "=", "Outback"));
                            break;
                    }
                    switch (SolarSystem.ChargeController)
                    {
                        case ChargeControllerType.Classic:
                            writer.WriteLine(string.Concat(CONFIGURATION_KEY_CHARGE_CONTROLLER, "=", "Classic"));
                            break;
                        case ChargeControllerType.Outback:
                            writer.WriteLine(string.Concat(CONFIGURATION_KEY_CHARGE_CONTROLLER, "=", "Outback"));
                            break;
                        case ChargeControllerType.TriStarTCP:
                            writer.WriteLine(string.Concat(CONFIGURATION_KEY_CHARGE_CONTROLLER, "=", "TriStarTCP"));
                            break;
                        case ChargeControllerType.TriStarRTU:
                            writer.WriteLine(string.Concat(CONFIGURATION_KEY_CHARGE_CONTROLLER, "=", "TriStarRTU"));
                            break;
                    }
                    writer.WriteLine(string.Concat(CONFIGURATION_KEY_MODBUS_SLAVE_IP, "=", ModbusConfiguration.ModbusSlaveIp));
                    writer.WriteLine(string.Concat(CONFIGURATION_KEY_MODBUS_PORT, "=", ModbusConfiguration.ModbusSlavePort));
                    writer.WriteLine(string.Concat(CONFIGURATION_KEY_WEB_PORT, "=", WebConfiguration.Port));
                    writer.WriteLine(string.Concat(CONFIGURATION_KEY_WEB_MAX_WORKER_THREAD_COUNT, "=", WebConfiguration.MaxWorkerThreadCount));
                    writer.WriteLine(string.Concat(CONFIGURATION_DHCP, "=", SystemConfiguration.DHCPEnabled ? "true" : "false"));
                    writer.WriteLine(string.Concat(CONFIGURATION_NETBIOSNAME, "=", SystemConfiguration.NetBiosName));
                    writer.WriteLine(string.Concat(CONFIGURATION_GATEWAY, "=", SystemConfiguration.GatewayIp));
                    writer.WriteLine(string.Concat(CONFIGURATION_SUBNET, "=", SystemConfiguration.SubnetMask));
                    writer.WriteLine(string.Concat(CONFIGURATION_DEVICE_IP, "=", SystemConfiguration.DeviceIp));
                    writer.WriteLine(string.Concat(CONFIGURATION_KEY_LCD, "=", SystemConfiguration.LCDEnabled ? "true" : "false"));
                    writer.Flush();
                    writer.Close();
                }
            }
        }


    }
}
